package com.effectiv.gooruda.rest.api.service;

import java.util.List;

import javax.jms.Message;
import javax.jms.ObjectMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.activemq.broker.jmx.BrokerViewMBean;
import org.apache.activemq.broker.jmx.QueueViewMBean;
import org.perf4j.aop.Profiled;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.jms.core.JmsTemplate;

import org.springframework.stereotype.Component;

import com.effectiv.gooruda.rest.api.domain.CloudMessage;
import com.effectiv.gooruda.rest.api.domain.CloudMessages;
import com.effectiv.gooruda.rest.api.exception.MessageOperationException;
import com.effectiv.gooruda.rest.api.operation.MessageOperations;
import com.effectiv.gooruda.security.rest.RESTSecurityUtil;

@Component
@Slf4j
public class MessageServiceImpl implements MessageOperations {

	@Autowired
	private JmsTemplate template;
	@Autowired
	private BrokerViewMBean brokerViewMBean;
	
	@Autowired
	private QueueViewMBeanLocator queueViewMBeanLocator;

	private final String QNAME_TEMPLATE = "q.";

	
	//UC : 006
	@Override
	@Profiled(level="INFO", message="Add messages")
	public void addMessages(String queueName, CloudMessages messages) {

		log.debug("Saving messages - {}", messages);

		for (CloudMessage cm : messages) {
			log.info("cm = {}", cm);
			template.execute(getDestinationName(queueName), new DefaultProduerCallback(cm));
		}

	}
	
	//UC : 007
	@Override
	public CloudMessages findAll(String queueName, int max, boolean delete) {
		SimpleBrowserCallback callback = new SimpleBrowserCallback(max);

		long count = template.browse(getDestinationName(queueName), callback);

		log.info("total messages = {}", count);

		List<Message> jmsMessages = callback.getMessages();

		CloudMessages cqMessages = new CloudMessages();
		QueueViewMBean queueMbean = null;
		if(delete){
			queueMbean = queueViewMBeanLocator.getQueueView(getDestinationName(queueName));
		}

		for (Message m : jmsMessages) {
			try {
				log.info("Message id - {}", m.getJMSMessageID());
				ObjectMessage o = (ObjectMessage) m;
				CloudMessage cqm = (CloudMessage) o.getObject();
				cqm.setId(m.getJMSCorrelationID());
				cqMessages.add(cqm);
				
				if(delete){
					queueMbean.removeMessage(m.getJMSMessageID());
				}

			}  catch (Exception e) {
				throw new MessageOperationException("Error processing message", e);
			}

		}
		return cqMessages;
	}
	
	//UC : 008
	@Override
	public void delete(String queueName, String messageId) {

		log.info("MessageId = {}", messageId);

		String messageSelector = "JMSCorrelationID = " + "'" + messageId + "'";
		log.info("messageSelector = {}", messageSelector);

		Message message = template.receiveSelected(
				getDestinationName(queueName), messageSelector);

		log.info("message = {}", message);
	}

	protected String getDestinationName(String queueName) {
		return QNAME_TEMPLATE + RESTSecurityUtil.getAppId() + "." + queueName;
	}

}
